package com.dcm.common.advice;

import com.dcm.common.annotation.Log;
import com.dcm.common.service.LogService;
import com.dcm.common.vo.LogMessage;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.CodeSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author:zhouyuhan
 * 时间: 2021/4/12 20:25
 */
@Slf4j
@Aspect
@Component
public class LogAspect {
    @Autowired
    private LogService logService;

    /**
     * 请求地址
     */
    private String requestPath = null;
    /**
     * 请求时间
     */
    private Date rightNow = null;
    /**
     * 操作人
     */
    private String user = null;
    /**
     * 请求
     */
    private HttpServletRequest request = null;


    /**
     * Controller层切点
     */
    @Pointcut("@annotation(com.dcm.common.annotation.Log)")
    public void controllerAspect() {

    }

    /**
     * 获取方法参数
     *
     * @param joinPoint
     * @return
     */
    public Map<String, Object> getNameAndValue(JoinPoint joinPoint) {
        HashMap<String, Object> param = new HashMap<>(32);
        //连接点上的参数
        Object[] paramValues = joinPoint.getArgs();
        //连接点上的签名
        String[] paramNames = ((CodeSignature) joinPoint.getSignature()).getParameterNames();
        for (int i = 0; i < paramNames.length; i++) {
            if (paramValues[i] instanceof Integer || paramValues[i] instanceof String) {
                param.put(paramNames[i], paramValues[i]);
            }
        }
        return param;
    }

    /**
     * @Description: 获取request
     */
    public HttpServletRequest getHttpServletRequest() {
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
        HttpServletRequest request = sra.getRequest();
        return request;
    }

    /**
     * 后置通知 用于拦截Controller层记录用户的操作
     * @param joinPoint
     */
    @After("controllerAspect()")
    public void after(JoinPoint joinPoint) {
        request = getHttpServletRequest();
        //目标对象的名称
        String targetName = joinPoint.getTarget().getClass().getName();
        //签名的标识符 方法名
        String methodName = joinPoint.getSignature().getName();
        //参数
        Object[] arguments = joinPoint.getArgs();
        Class<?> targetClass = null;
        try {
            targetClass = Class.forName(targetName);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        Method[] methods = targetClass.getMethods();
        String title;
        String action;
        Class<?>[] clazzs;
        for (Method method : methods) {
            if (method.getName().equals(methodName)) {
                clazzs = method.getParameterTypes();
                if (clazzs != null && clazzs.length == arguments.length && method.getAnnotation(Log.class) != null) {
                    request = getHttpServletRequest();
                    requestPath = request.getServletPath();

                    user = (String) request.getSession().getAttribute("user");
                    title = method.getAnnotation(Log.class).title();
                    action = method.getAnnotation(Log.class).action();
                    rightNow = new Date();
                    LogMessage log = new LogMessage(user, requestPath,rightNow+"", getNameAndValue(joinPoint).toString(), title, action);
                    logService.writeLog(log);
                    break;
                }
            }
        }
    }

}
